package cn.lg.soar.database.translate;

import cn.lg.soar.common.util.data.DataUtil;
import cn.lg.soar.common.util.trans.TranslateHelpUtils;
import cn.lg.soar.common.util.trans.handler.ITranslateHandler;
import cn.lg.soar.common.util.trans.model.TranslateContext;
import cn.lg.soar.database.translate.mapper.TranslateMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ConcurrentReferenceHashMap;

import java.lang.annotation.Annotation;
import java.util.Map;

/**
 * @author luguoxiang
 * @date 2022/6/11
 * 开源项目：https://gitee.com/lgx1992/lg-soar 求star！请给我star！请帮我点个star！
 */
public class TranslateByEntityHandler implements ITranslateHandler<Object> {

    private final static Map<Annotation, IConfig> CACHE = new ConcurrentReferenceHashMap<>();
    private final static Map<Annotation, IConfig> TOJAVA_CACHE = new ConcurrentReferenceHashMap<>();

    @Autowired
    protected TranslateMapper translateMapper;

    @Override
    public Object convertByJava(Object value, Annotation annotation, TranslateContext<Object> context) {
        IConfig config = CACHE.computeIfAbsent(annotation, key -> {
            // 解析配置
            return new TextConfig((TranslateByEntity) annotation, translateMapper, false);
        });
        // 读取缓存
        String text = config.get(value);
        if (text != null) {
            return text;
        }
        return TranslateHelpUtils.mapper(value, config::get);
    }

    @Override
    public Object convertToJava(Object value, Annotation annotation, TranslateContext<Object> context) {
        IConfig config = TOJAVA_CACHE.computeIfAbsent(annotation, key -> {
            // 解析配置
            return new TextConfig((TranslateByEntity) annotation, translateMapper, true);
        });

        Class<?> javaType = context.getJavaType();
        String strValue = value.toString();
        Object o = config.get(strValue);
        if (o != null) {
            return DataUtil.to(javaType, o);
        }
        o = TranslateHelpUtils.remapper(javaType, strValue, config::get);
        if (o != null) {
            return o;
        }
        return null;
    }

}
